package sma.images.slides.client.slider;

import com.google.gwt.dom.client.Style;
import com.google.gwt.dom.client.Style.Position;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.dom.client.Style.Visibility;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.MouseOverEvent;
import com.google.gwt.event.dom.client.MouseOverHandler;
import com.google.gwt.user.client.ui.FlexTable;

public abstract class ControlsTable extends FlexTable {

	private ControlLabel playPauseLabel;
	private ISlidesCtrl slideCtrl;
	
	public ControlsTable(ISlidesCtrl slideCtrl_){
		super();
		slideCtrl = slideCtrl_;
		initControlWidget(21, 20, Visibility.VISIBLE);
		
		initPlayPauseControlWidget();
		
		setWidget(0, 0, playPauseLabel);
		getCellFormatter().setWidth(0, 1, "80%");
		
		initNumberLabels();
	}
	
	public void setPlayPauseControlVisible(Visibility v_){
		playPauseLabel.getElement().getStyle().setVisibility(v_);
	}
	
	private void initControlWidget(int zIndex_, int left_, Visibility v_){
		Style style = getElement().getStyle();
		style.setTop(30, Unit.PX);
		style.setZIndex(zIndex_);
		style.setPosition(Position.RELATIVE);
		style.setVisibility(v_);
		style.setLeft(left_, Unit.PX);
	}
	
	private void initPlayPauseControlWidget(){
		playPauseLabel = new ControlLabel("||");
		playPauseLabel.setWidth("60px");
		playPauseLabel.getElement().getStyle().setVisibility(Visibility.HIDDEN);
		
		playPauseLabel.addMouseOverHandler(new MouseOverHandler() {
			
			@Override
			public void onMouseOver(MouseOverEvent event) {
				playPauseLabel.getElement().getStyle().setVisibility(Visibility.VISIBLE);
			}
		});
		
		playPauseLabel.getElement().setAttribute("isPlaying", "true");
		playPauseLabel.addClickHandler(new ClickHandler() {
			
			@Override
			public void onClick(ClickEvent event) {
				if( Boolean.parseBoolean( playPauseLabel.getElement().getAttribute("isPlaying") ) ){
					onPlayAction();
				} else {
					onPauseAction();
				}
			}
		});
	}
	
	private void onPlayAction(){
		playPauseLabel.setText("||");
		playPauseLabel.getElement().setAttribute("isPlaying", "false");
		onPlay();
	}
	
	private void onPauseAction(){
		playPauseLabel.setText("|>");
		playPauseLabel.getElement().setAttribute("isPlaying", "true");
		onPause();
	}
	
	protected void onNumberLabelClicled(int num_) {
		onPauseAction();
		selectNumber(slideCtrl.getCurrentIndex(), false);
		selectNumber(num_, true);
		onSlideSelected(num_);
	}
	
	protected void selectNumber(int slideIndex_, boolean isSelected_){
		getNumberLabelWidget( slideIndex_ ).setSelected(isSelected_);
	}
	
	protected void selectNearNumbers(int slideIndex_, boolean isSelected_){
		selectNextNumber(slideIndex_, isSelected_);
		selectPreviousNumber(slideIndex_, isSelected_);
	}
	
	private void selectPreviousNumber(int slideIndex_, boolean isSelected_){
		int slideIndex = slideCtrl.getPreviousIndex(slideIndex_);
		getNumberLabelWidget(slideIndex).setSelected(isSelected_);
	}
	
	private void selectNextNumber(int slideIndex_, boolean isSelected_){
		int slideIndex = slideCtrl.getNextIndex(slideIndex_);
		getNumberLabelWidget(slideIndex).setSelected(isSelected_);
	}
	
	public ControlLabel getNumberLabelWidget(int number_){
		return number_>=0&&number_<slideCtrl.getSlidesCount() ? 
				((ControlLabel)getWidget(0, number_+2)) 
				: null;
	}
	
	private void initNumberLabels() {
		for(int i=0; i<slideCtrl.getSlidesCount(); i++){
			ControlLabel l = createNumberLabel(i);
			setWidget(0, i+2, l);
		}
		getNumberLabelWidget(0).setSelected(true);
	}
	
	private ControlLabel createNumberLabel(final int num_) {
		ControlLabel l = new ControlLabel( Integer.toString(num_+1));
		l.setWidth("15px");
		l.addClickHandler(new ClickHandler() {
			
			@Override
			public void onClick(ClickEvent event) {
				onNumberLabelClicled(num_);
			}
		});
		
		return l;
	}
	
	protected abstract void onPlay();
	protected abstract void onPause();
	protected abstract void onSlideSelected(int num_);
}
